// 新增、修改、查看功能的复用

export default {
  model: {
    prop: 'gVisible',
    event: 'update:gVisible'
  },
  props: {
    // 弹框是否显示
    gVisible: {
      type: Boolean,
      default: false
    },
    // 弹框宽度
    width: {
      type: [String, Number],
      default: 520
    },
    // 是否双列模式
    double: {
      type: Boolean,
      default: true
    }
  },
  data () {
    return {
      addEditConfig: {
        moduleName: '模块xx',
        primaryKey: 'id',
        addApiFn: null,
        editApiFn: null,
        infoApiFn: null,
        beforeShowInfoFn: null, // 显示详情前执行函数(用于将后端返回的数据进行处理，再赋给表单)
        beforeRequestFn: null, // 新增或修改求前执行函数,
        afterRequestFn: null, // 新增或修改请求后执行函数
        beforeCloseFn: null // 关闭弹框前执行函数
      },
      gFormLoading: false,
      // 表单禁用
      gFormDisabled: false,
      // 表单数据
      gFormData: {}
    }
  },
  computed: {
    // 表单label布局
    gLabelCol () {
      return this.double ? { span: 6 } : { span: 6 }
    },
    // 表单控件布局
    gWrapperCol () {
      return this.double ? { span: 16 } : { span: 14 }
    },
    // 标题
    gFormTitle () {
      const { moduleName, primaryKey } = this.addEditConfig
      if (this.gFormDisabled) {
        return '查看' + moduleName
      } else if (this.gFormData[primaryKey]) {
        return '编辑' + moduleName
      } else {
        return '新增' + moduleName
      }
    }
  },
  created () {
    // 保存表单赶紧的初始数据
    this.gInitFormData = JSON.stringify(this.gFormData)
  },
  methods: {
    /**
    * 删除之后的回调函数
    * @param {*} requestData 要提交的数据
    * @param {*} data  选中的数据或点击的数据
    */
    gShowDetail (data, type = 'edit') {
      if (!['edit', 'see'].includes(type)) {
        return this.$message.warning('传入type错误，支持see、add、edit')
      }
      if (type === 'see') {
        this.gFormDisabled = true
      }
      const { infoApiFn, primaryKey, beforeShowInfoFn } = this.addEditConfig
      if (!data[primaryKey]) {
        return this.$message.warning(`查找数据主键：${primaryKey}不存在，前端代码错误`)
      }
      // 请求数据，这里提交data是为了增强，不一定查找只要交主键，提供给api函数自主取值
      infoApiFn(data).then((res) => {
        // 1. 调用外部处理数据中间件
        let responeData = res
        if (beforeShowInfoFn && typeof beforeShowInfoFn === 'function') {
          // 外部对数据加工处理
          responeData = this.addEditConfig.beforeShowInfoFn(res)
        }
        // 2. 赋值给表单
        this.gFormData = responeData
        // 3. 打开弹框
        this.$emit('update:gVisible', true)
      }).catch(err => {
        console.log('获取详情出错', err)
      })
    },
    // 表单提交
    gFormSubmit () {
      // 1. 表单验证
      this.$refs.gFormRef.validate(async (valid) => {
        // 验证不通过
        if (!valid) return
        let cloneData = JSON.parse(JSON.stringify(this.gFormData))
        // 结构
        const { addApiFn, editApiFn, primaryKey, beforeRequestFn, afterRequestFn } = this.addEditConfig
        // 2. 数据处理(中间件完成)
        if (beforeRequestFn && typeof beforeRequestFn === 'function') {
          // 外部对数据加工处理
          cloneData = await beforeRequestFn(cloneData)
        }
        // 3. 发起请求
        // 4. 提示成功
        this.gFormLoading = true
        let responseData = null
        try {
          if (this.gFormData[primaryKey]) {
            responseData = await editApiFn(cloneData) // 修改
            this.$message.success('修改成功')
          } else {
            responseData = await addApiFn(cloneData) // 新增
            this.$message.success('新增成功')
          }
          this.gFormLoading = false
        } catch (error) {
          this.gFormLoading = false
          return console.log('新增或修改出错', error)
        }
        // 5. 关闭弹框
        this.gFormCancel()
         // 6. 结果处理中间件()
        if (afterRequestFn && typeof afterRequestFn === 'function') {
          // 外部对数据加工处理
          await afterRequestFn(responseData)
        }
        // 7. 刷新列表
        this.$emit('refreshList')
      })
    },
    // 点击弹框遮罩或取消或关闭按钮触发
    async gFormCancel () {
      // 1. 表单重置
      this.gFormData = JSON.parse(this.gInitFormData)
      // 2.移除校验
      this.$refs.gFormRef.resetFields()
      // 3. 关闭禁用
      this.gFormDisabled = false
      // 4. 执行中间件，外部操作
      const { beforeCloseFn } = this.addEditConfig
      if (beforeCloseFn && typeof beforeCloseFn === 'function') {
        await this.addEditConfig.beforeCloseFn()
      }
      // 5 关闭弹框
      this.$emit('update:gVisible', false)
    }
  }
}
